package org.haifi.game.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.session.IoSession;
import org.haifi.game.dao.GameUserMapper;
import org.haifi.game.model.GameUser;
import org.haifi.game.remoting.RemotingFactory;
import org.haifi.game.service.GameUserManager;
import org.haifi.game.util.Base64Util;
import org.haifi.game.util.GameUtil;
import org.haifi.game.util.Md5Util;
import org.haifi.game.util.SessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;

@Component
public class GameUserManagerImpl implements GameUserManager {
	@Override
	public GameUser getByName(String username) {
		if (StringUtils.isEmpty(username)) {
			log.error("ERROR search user with null username.");
			return null;
		}
		return gameUserMapper.getByName(username);
	}

	@Override
	public GameUser createNewUser(String username, String password) {
		// 新建帐号

		// 密码加密
		password = encodePassword(password);

		GameUser gameUser = new GameUser();
		gameUser.setUsername(username);
		gameUser.setPassword(password);
		Date date = new Date();
		gameUser.setLoginDate(date);
		gameUser.setRegDate(date);
		gameUser.setLoginDateByDay(date);
		gameUserMapper.insert(gameUser);
		return gameUser;
	}

	@Override
	public void resetPassword(GameUser gameUser, String newPassword) {
		// 重置密码

		// 密码加密
		newPassword = encodePassword(newPassword);
		gameUser.setPassword(newPassword);
		gameUserMapper.update(gameUser);
	}

	public String encodePassword(String password) {
		// 将密码进行加密，并返回加密后的字符串
		return Md5Util.md5(password);
	}

	public String login(IoSession ioSession, GameUser gameUser) {
		// TODO:如果当前有其它玩家已经登陆这个帐号，则将其它玩家踢下线

		// 帐号登陆成功
		ioSession.setAttribute(SessionUtils.USER, gameUser);
		// 用户登陆，记录在userSession中
		SessionUtils.addNewUserIoSession(ioSession);

		Date now = new Date();
		if (!DateUtils.isSameDay(gameUser.getLoginDate(), now)) {
			// 如果上次登陆不是本日登陆，记录上一次登陆日期
			gameUser.setLoginDateByDay(gameUser.getLoginDate());
		}
		gameUser.setLoginDate(new Date());

		// 登陆成功后生成token
		String token = generateLoginToken(gameUser);
		gameUserMapper.update(gameUser);
		return token;
	}

	public String generateLoginToken(GameUser gameUser) {
		// 生成用户免认证登陆的token
		// TODO:需要查一下，玩家的连接端口会不会变，如果端口号不变的话，就强制端口号要相同，暂时不验证端口号
		// token中需要带着user.id,user.name不然gameServer上无法知道这些信息

		// token只在24小时内有效，因此，如果玩家在线超过24小时，客户端应该主动重新获取一次(或者服务器端主推一次也可以)

		// token=user.id|user.name|ip|当前时间（毫秒值)

		String ip = SessionUtils.getCurrentIp();

		String str = gameUser.getId() + "|" + gameUser.getUsername() + "|" + ip
				+ "|" + System.currentTimeMillis();

		String token2 = Base64Util.encode(str);

		// 需要此6位与客户端获得的token进行拼接，才是最终的token，明白了，此token必须带着userId

		// 最终token=uid(16位，不足16位，中间补随机大小写字母插入)+生成的base64编码(不包含最后6位，最后6位存在gameUser对象上)

		// 生成前16位
		String token1 = String.valueOf(gameUser.getId());
		List<Character> list = Lists.newArrayListWithExpectedSize(16);
		for (char c : token1.toCharArray()) {
			list.add(c);
		}
		while (list.size() < 16) {
			char c = GameUtil.nextChar();
			list.add(GameUtil.nextInt(list.size() + 1), c);
		}
		StringBuilder sb = new StringBuilder();
		for (char c : list) {
			sb.append(c);
		}
		token1 = sb.toString();
		// 最终完整的token
		String finalToken = token1 + token2;
		// 最后6位存储在gameUser上
		gameUser.setToken(finalToken.substring(finalToken.length() - 6));
		// 返回除最后6位的其它字符
		return finalToken.substring(0, finalToken.length() - 6);

	}

	@Autowired
	private RemotingFactory remotingFactory;
	
	@Autowired
	private GameUserMapper gameUserMapper;
	
	private static final Log log = LogFactory.getLog(GameUserManagerImpl.class);

}
